<template>
  <div class="map-container">
    <div id="map" class="map"></div>
    
    <!-- 工具栏 -->
    <div class="toolbar">
      <button @click="toggleMeasure('LineString')" :class="{ active: measureType === 'LineString' }">
        <strong>测距</strong>
      </button>
      <button @click="toggleMeasure('Polygon')" :class="{ active: measureType === 'Polygon' }">
        <strong>测面</strong>
      </button>
      <button @click="clearMeasure">
        <strong>清除</strong>
      </button>
    </div>

  </div>
</template>

<script>
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
import { XYZ, Vector as VectorSource } from 'ol/source';
import { Draw, Snap } from 'ol/interaction';
import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style';
import { getArea, getLength } from 'ol/sphere';
import { unByKey } from 'ol/Observable';
import Overlay from 'ol/Overlay';
import { fromLonLat, transform } from 'ol/proj';
import LineString from 'ol/geom/LineString';
import Polygon from 'ol/geom/Polygon';

export default {
  name: 'MeasureMap',
  data() {
    return {
      map: null,
      measureType: null,
      draw: null,
      snap: null,
      vectorLayer: null,
      measureTooltipElement: null,
      measureTooltip: null,
      helpTooltipElement: null,
      helpTooltip: null,
      sketch: null,
      listener: null
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    initMap() {
      // 创建矢量图层用于绘制
      const source = new VectorSource();
      this.vectorLayer = new VectorLayer({
        source: source,
        style: new Style({
          fill: new Fill({
            color: 'rgba(24, 144, 255, 0.2)'
          }),
          stroke: new Stroke({
            color: '#1890ff',
            width: 3
          }),
          image: new CircleStyle({
            radius: 6,
            fill: new Fill({
              color: '#1890ff'
            })
          })
        })
      });

      // 创建地图
      this.map = new Map({
        target: 'map',
        layers: [
          new TileLayer({
            source: new XYZ({
              url: 'https://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}'
            })
          }),
          this.vectorLayer
        ],
        view: new View({
          center: fromLonLat([116.397428, 39.90923]),
          zoom: 12,
          projection: 'EPSG:3857'
        })
      });

      // 创建帮助提示
      this.createHelpTooltip();
      // 创建测量提示
      this.createMeasureTooltip();

      // 鼠标移动事件
      this.map.on('pointermove', this.pointerMoveHandler);
    },

    toggleMeasure(type) {
      // 如果已经在测量，先移除当前的绘制工具
      if (this.draw) {
        this.map.removeInteraction(this.draw);
        this.map.removeInteraction(this.snap);
      }

      // 如果点击的是当前激活的类型，则停止测量
      if (this.measureType === type) {
        this.measureType = null;
        return;
      }

      this.measureType = type;
      
      // 创建绘制工具
      this.draw = new Draw({
        source: this.vectorLayer.getSource(),
        type: type,
        style: new Style({
          fill: new Fill({
            color: 'rgba(24, 144, 255, 0.1)'
          }),
          stroke: new Stroke({
            color: '#1890ff',
            lineDash: [10, 10],
            width: 2.5
          }),
          image: new CircleStyle({
            radius: 6,
            stroke: new Stroke({
              color: '#1890ff'
            }),
            fill: new Fill({
              color: '#fff'
            })
          })
        })
      });

      this.map.addInteraction(this.draw);

      // 添加捕捉功能
      this.snap = new Snap({ source: this.vectorLayer.getSource() });
      this.map.addInteraction(this.snap);

      // 绘制开始事件
      this.draw.on('drawstart', (evt) => {
        this.sketch = evt.feature;

        let tooltipCoord = evt.coordinate;

        // 添加绘制过程中的监听器
        this.listener = this.sketch.getGeometry().on('change', (evt) => {
          const geom = evt.target;
          let output;
          if (geom instanceof LineString) {
            output = this.formatLength(geom);
            tooltipCoord = geom.getLastCoordinate();
          } else if (geom instanceof Polygon) {
            output = this.formatArea(geom);
            tooltipCoord = geom.getInteriorPoint().getCoordinates();
          }
          this.measureTooltipElement.innerHTML = output;
          this.measureTooltip.setPosition(tooltipCoord);
        });
      });

      // 绘制结束事件
      this.draw.on('drawend', (evt) => {
        // 获取最终绘制的要素
        const feature = evt.feature;
        const geometry = feature.getGeometry();
        let tooltipCoord;
        let output;

        // 计算最终的测量结果
        if (geometry instanceof LineString) {
          output = this.formatLength(geometry);
          tooltipCoord = geometry.getLastCoordinate();
        } else if (geometry instanceof Polygon) {
          output = this.formatArea(geometry);
          tooltipCoord = geometry.getInteriorPoint().getCoordinates();
        }

        // 创建新的tooltip元素
        const tooltipElement = document.createElement('div');
        tooltipElement.className = 'measure-tooltip';
        tooltipElement.innerHTML = output;

        // 创建新的overlay
        const tooltip = new Overlay({
          element: tooltipElement,
          offset: [0, -15],
          positioning: 'bottom-center',
          stopEvent: false,
          position: tooltipCoord
        });

        // 添加到地图
        this.map.addOverlay(tooltip);

        // 清理绘制过程中的tooltip
        if (this.measureTooltipElement && this.measureTooltipElement.parentNode) {
          this.measureTooltipElement.parentNode.removeChild(this.measureTooltipElement);
        }
        this.measureTooltipElement = null;

        // 创建新的tooltip用于下一次测量
        this.createMeasureTooltip();
        
        this.sketch = null;
        unByKey(this.listener);
      });
    },

    createMeasureTooltip() {
      if (this.measureTooltipElement) {
        this.measureTooltipElement.parentNode.removeChild(this.measureTooltipElement);
      }
      this.measureTooltipElement = document.createElement('div');
      this.measureTooltipElement.className = 'measure-tooltip measure-tooltip-dynamic';
      this.measureTooltip = new Overlay({
        element: this.measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center',
        stopEvent: false
      });
      this.map.addOverlay(this.measureTooltip);
    },

    createHelpTooltip() {
      if (this.helpTooltipElement) {
        this.helpTooltipElement.parentNode.removeChild(this.helpTooltipElement);
      }
      this.helpTooltipElement = document.createElement('div');
      this.helpTooltipElement.className = 'help-tooltip';
      this.helpTooltip = new Overlay({
        element: this.helpTooltipElement,
        offset: [15, 0],
        positioning: 'center-left'
      });
      this.map.addOverlay(this.helpTooltip);
    },

    pointerMoveHandler(evt) {
      if (evt.dragging) {
        return;
      }
      
      // 只有在绘制过程中才显示提示
      if (!this.sketch) {
        this.helpTooltipElement.style.display = 'none';
        return;
      }

      this.helpTooltipElement.style.display = 'block';
      const helpMsg = this.measureType === 'LineString' ? 
        '单击继续绘制线段' : '单击继续绘制多边形';

      this.helpTooltipElement.innerHTML = helpMsg;
      this.helpTooltip.setPosition(evt.coordinate);
    },

    formatLength(line) {
      const coordinates = line.getCoordinates();
      const length = getLength(line, {
        projection: 'EPSG:3857'
      });
      let output;
      if (length > 100) {
        output = `<div class="measure-result">
          <span class="measure-value">${(Math.round(length / 1000 * 100) / 100)}</span>
          <span class="measure-unit">km</span>
        </div>`;
      } else {
        output = `<div class="measure-result">
          <span class="measure-value">${(Math.round(length * 100) / 100)}</span>
          <span class="measure-unit">m</span>
        </div>`;
      }
      return output;
    },

    formatArea(polygon) {
      const area = getArea(polygon, {
        projection: 'EPSG:3857'
      });
      let output;
      if (area > 10000) {
        output = `<div class="measure-result">
          <span class="measure-value">${(Math.round(area / 1000000 * 100) / 100)}</span>
          <span class="measure-unit">km²</span>
        </div>`;
      } else {
        output = `<div class="measure-result">
          <span class="measure-value">${(Math.round(area * 100) / 100)}</span>
          <span class="measure-unit">m²</span>
        </div>`;
      }
      return output;
    },

    clearMeasure() {
      // 清除矢量图层中的所有要素
      this.vectorLayer.getSource().clear();
      
      // 获取所有overlay并清理
      const overlays = this.map.getOverlays().getArray();
      // 先移除所有measure-tooltip类的元素
      document.querySelectorAll('.measure-tooltip').forEach(element => {
        if (element && element.parentNode) {
          element.parentNode.removeChild(element);
        }
      });
      
      // 然后移除所有overlay
      overlays.forEach(overlay => {
        const element = overlay.getElement();
        if (element && element.parentNode) {
          element.parentNode.removeChild(element);
        }
        this.map.removeOverlay(overlay);
      });
      
      // 确保所有tooltip元素被清理
      if (this.measureTooltipElement && this.measureTooltipElement.parentNode) {
        this.measureTooltipElement.parentNode.removeChild(this.measureTooltipElement);
      }
      if (this.helpTooltipElement && this.helpTooltipElement.parentNode) {
        this.helpTooltipElement.parentNode.removeChild(this.helpTooltipElement);
      }
      
      // 重置所有tooltip相关变量
      this.measureTooltipElement = null;
      this.helpTooltipElement = null;
      this.measureTooltip = null;
      this.helpTooltip = null;
      
      // 重新创建帮助提示和测量提示
      this.createHelpTooltip();
      this.createMeasureTooltip();
      
      // 重置测量状态
      this.measureType = null;
      this.sketch = null;
      
      // 移除绘制和捕捉交互
      if (this.draw) {
        this.map.removeInteraction(this.draw);
        this.draw = null;
      }
      if (this.snap) {
        this.map.removeInteraction(this.snap);
        this.snap = null;
      }
      
      // 移除监听器
      if (this.listener) {
        unByKey(this.listener);
        this.listener = null;
      }
    }
  },
  beforeDestroy() {
    if (this.map) {
      this.map.setTarget(null);
      this.map = null;
    }
  }
};
</script>

<style scoped>
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');

.map-container {
  position: relative;
  width: 100%;
  height: 100vh;
}

.map {
  width: 100%;
  height: 100%;
}

.toolbar {
  position: absolute;
  top: 10px;
  left: 10px;
  background: white;
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
  z-index: 1000;
}

.toolbar button {
  margin: 0 5px;
  padding: 5px 10px;
  border: 1px solid #ccc;
  background: white;
  cursor: pointer;
  border-radius: 3px;
  transition: all 0.3s;
  font-size: 14px;
  min-width: 60px;
  font-weight: 500;
  letter-spacing: 1px;
}

.toolbar button.active {
  background: #1890ff;
  color: white;
  border-color: #1890ff;
  font-weight: 600;
  text-shadow: 0 1px 2px rgba(0,0,0,0.1);
}

.toolbar button:hover {
  background: #f5f5f5;
  border-color: #40a9ff;
  color: #40a9ff;
}

.toolbar button.active:hover {
  background: #40a9ff;
  color: white;
}

::v-deep .measure-tooltip {
  position: relative;
  background: rgba(0, 0, 0, 0.75);
  padding: 4px 8px;
  border-radius: 4px;
  color: white;
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 2px 6px rgba(0,0,0,0.2);
  text-shadow: 0 1px 2px rgba(0,0,0,0.2);
  line-height: 1.4;
}

::v-deep .measure-result {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

::v-deep .measure-value {
  font-size: 16px;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0,0,0,0.3);
  letter-spacing: 0.5px;
}

::v-deep .measure-unit {
  font-size: 13px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.85);
  margin-left: 2px;
  letter-spacing: 0.5px;
}

::v-deep .measure-tooltip-dynamic {
  opacity: 1;
  font-weight: 600;
  animation: fadeIn 0.2s ease-out;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(-5px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

::v-deep .help-tooltip {
  position: relative;
  background: rgba(0, 0, 0, 0.75);
  padding: 6px 12px;
  border-radius: 4px;
  border: none;
  color: white;
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 2px 6px rgba(0,0,0,0.2);
  letter-spacing: 0.3px;
  text-shadow: 0 1px 2px rgba(0,0,0,0.2);
  line-height: 1.4;
  animation: fadeIn 0.2s ease-out;
}
</style> 